


<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>torch.serialization &mdash; PyTorch master documentation</title>
  

  
  
  
  
    <link rel="canonical" href="https://pytorch.org/docs/stable/_modules/torch/serialization.html"/>
  

  

  
  
    

  

  <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
  <!-- <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.0-beta/dist/katex.min.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/jit.css" type="text/css" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/katex-math.css" type="text/css" />
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" /> 

  
  <script src="../../_static/js/modernizr.min.js"></script>

  <!-- Preload the theme fonts -->

<link rel="preload" href="../../_static/fonts/FreightSans/freight-sans-book.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../../_static/fonts/FreightSans/freight-sans-medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../../_static/fonts/IBMPlexMono/IBMPlexMono-Medium.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../../_static/fonts/FreightSans/freight-sans-bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../../_static/fonts/FreightSans/freight-sans-medium-italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="../../_static/fonts/IBMPlexMono/IBMPlexMono-SemiBold.woff2" as="font" type="font/woff2" crossorigin="anonymous">

<!-- Preload the katex fonts -->

<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Math-Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size1-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size4-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size2-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size3-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
<link rel="preload" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Caligraphic-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous">
</head>

<div class="container-fluid header-holder tutorials-header" id="header-holder">
  <div class="container">
    <div class="header-container">
      <a class="header-logo" href="https://pytorch.org/" aria-label="PyTorch"></a>

      <div class="main-menu">
        <ul>
          <li>
            <a href="https://pytorch.org/get-started">Get Started</a>
          </li>

          <li>
            <div class="ecosystem-dropdown">
              <a id="dropdownMenuButton" data-toggle="ecosystem-dropdown">
                Ecosystem
              </a>
              <div class="ecosystem-dropdown-menu">
                <a class="nav-dropdown-item" href="https://pytorch.org/hub"">
                  <span class=dropdown-title>Models (Beta)</span>
                  <p>Discover, publish, and reuse pre-trained models</p>
                </a>
                <a class="nav-dropdown-item" href="https://pytorch.org/ecosystem">
                  <span class=dropdown-title>Tools & Libraries</span>
                  <p>Explore the ecosystem of tools and libraries</p>
                </a>
              </div>
            </div>
          </li>

          <li>
            <a href="https://pytorch.org/mobile">Mobile</a>
          </li>

          <li>
            <a href="https://pytorch.org/blog/">Blog</a>
          </li>

          <li>
            <a href="https://pytorch.org/tutorials">Tutorials</a>
          </li>

          <li class="active">
            <a href="https://pytorch.org/docs/stable/index.html">Docs</a>
          </li>

          <li>
            <div class="resources-dropdown">
              <a id="resourcesDropdownButton" data-toggle="resources-dropdown">
                Resources
              </a>
              <div class="resources-dropdown-menu">
                <a class="nav-dropdown-item" href="https://pytorch.org/resources"">
                  <span class=dropdown-title>Developer Resources</span>
                  <p>Find resources and get questions answered</p>
                </a>
                <a class="nav-dropdown-item" href="https://pytorch.org/features">
                  <span class=dropdown-title>About</span>
                  <p>Learn about PyTorch’s features and capabilities</p>
                </a>
              </div>
            </div>
          </li>

          <li>
            <a href="https://github.com/pytorch/pytorch">Github</a>
          </li>
        </ul>
      </div>

      <a class="main-menu-open-button" href="#" data-behavior="open-mobile-menu"></a>
    </div>

  </div>
</div>


<body class="pytorch-body">

   

    

    <div class="table-of-contents-link-wrapper">
      <span>Table of Contents</span>
      <a href="#" class="toggle-table-of-contents" data-behavior="toggle-table-of-contents"></a>
    </div>

    <nav data-toggle="wy-nav-shift" class="pytorch-left-menu" id="pytorch-left-menu">
      <div class="pytorch-side-scroll">
        <div class="pytorch-menu pytorch-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          <div class="pytorch-left-menu-search">
            

            
              
              
                <div class="version">
                  master (1.5.0 )
                </div>
              
            

            


  


<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
    <input type="text" name="q" placeholder="Search Docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

            
          </div>

          
<div>
  <a style="color:#F05732" href="https://pytorch.org/docs/stable/_modules/torch/serialization.html">
    You are viewing unstable developer preview docs.
    Click here to view docs for latest stable release.
  </a>
</div>

            
            
              
            
            
              <p class="caption"><span class="caption-text">Notes</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../notes/amp_examples.html">Automatic Mixed Precision examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/autograd.html">Autograd mechanics</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/broadcasting.html">Broadcasting semantics</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/cpu_threading_torchscript_inference.html">CPU threading and TorchScript inference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/cuda.html">CUDA semantics</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/ddp.html">Distributed Data Parallel</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/extending.html">Extending PyTorch</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/faq.html">Frequently Asked Questions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/large_scale_deployments.html">Features for large-scale deployments</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/multiprocessing.html">Multiprocessing best practices</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/randomness.html">Reproducibility</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/serialization.html">Serialization semantics</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notes/windows.html">Windows FAQ</a></li>
</ul>
<p class="caption"><span class="caption-text">Language Bindings</span></p>
<ul>
<li class="toctree-l1"><a class="reference external" href="https://pytorch.org/cppdocs/">C++ API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../packages.html">Javadoc</a></li>
</ul>
<p class="caption"><span class="caption-text">Python API</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../torch.html">torch</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../nn.html">torch.nn</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../nn.functional.html">torch.nn.functional</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tensors.html">torch.Tensor</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tensor_attributes.html">Tensor Attributes</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tensor_view.html">Tensor Views</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../autograd.html">torch.autograd</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cuda.html">torch.cuda</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../amp.html">torch.cuda.amp</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../distributed.html">torch.distributed</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../distributions.html">torch.distributions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../hub.html">torch.hub</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../jit.html">torch.jit</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../nn.init.html">torch.nn.init</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../onnx.html">torch.onnx</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../optim.html">torch.optim</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../quantization.html">Quantization</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rpc/index.html">Distributed RPC Framework</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../random.html">torch.random</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../sparse.html">torch.sparse</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../storage.html">torch.Storage</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../bottleneck.html">torch.utils.bottleneck</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../checkpoint.html">torch.utils.checkpoint</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cpp_extension.html">torch.utils.cpp_extension</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../data.html">torch.utils.data</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dlpack.html">torch.utils.dlpack</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../model_zoo.html">torch.utils.model_zoo</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tensorboard.html">torch.utils.tensorboard</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../type_info.html">Type Info</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../named_tensor.html">Named Tensors</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../name_inference.html">Named Tensors operator coverage</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../__config__.html">torch.__config__</a></li>
</ul>
<p class="caption"><span class="caption-text">Libraries</span></p>
<ul>
<li class="toctree-l1"><a class="reference external" href="https://pytorch.org/audio">torchaudio</a></li>
<li class="toctree-l1"><a class="reference external" href="https://pytorch.org/text">torchtext</a></li>
<li class="toctree-l1"><a class="reference external" href="https://pytorch.org/elastic/">TorchElastic</a></li>
<li class="toctree-l1"><a class="reference external" href="https://pytorch.org/serve">TorchServe</a></li>
<li class="toctree-l1"><a class="reference external" href="http://pytorch.org/xla/">PyTorch on XLA Devices</a></li>
</ul>
<p class="caption"><span class="caption-text">Community</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../community/contribution_guide.html">PyTorch Contribution Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../community/governance.html">PyTorch Governance</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../community/persons_of_interest.html">PyTorch Governance | Persons of Interest</a></li>
</ul>

            
          

        </div>
      </div>
    </nav>

    <div class="pytorch-container">
      <div class="pytorch-page-level-bar" id="pytorch-page-level-bar">
        <div class="pytorch-breadcrumbs-wrapper">
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="pytorch-breadcrumbs">
    
      <li>
        <a href="../../index.html">
          
            Docs
          
        </a> &gt;
      </li>

        
          <li><a href="../index.html">Module code</a> &gt;</li>
        
          <li><a href="../torch.html">torch</a> &gt;</li>
        
      <li>torch.serialization</li>
    
    
      <li class="pytorch-breadcrumbs-aside">
        
      </li>
    
  </ul>

  
</div>
        </div>

        <div class="pytorch-shortcuts-wrapper" id="pytorch-shortcuts-wrapper">
          Shortcuts
        </div>
      </div>

      <section data-toggle="wy-nav-shift" id="pytorch-content-wrap" class="pytorch-content-wrap">
        <div class="pytorch-content-left">

        
          
          <div class="rst-content">
          
            <div role="main" class="main-content" itemscope="itemscope" itemtype="http://schema.org/Article">
             <article itemprop="articleBody" id="pytorch-article" class="pytorch-article">
              
  <h1>Source code for torch.serialization</h1><div class="highlight"><pre>
<span></span><span class="kn">import</span> <span class="nn">difflib</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">io</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">import</span> <span class="nn">struct</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">torch</span>
<span class="kn">import</span> <span class="nn">tarfile</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">warnings</span>
<span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">closing</span><span class="p">,</span> <span class="n">contextmanager</span>
<span class="kn">from</span> <span class="nn">._utils</span> <span class="kn">import</span> <span class="n">_import_dotted_name</span>
<span class="kn">from</span> <span class="nn">._six</span> <span class="kn">import</span> <span class="n">string_classes</span> <span class="k">as</span> <span class="n">_string_classes</span><span class="p">,</span> <span class="n">PY2</span>
<span class="kn">from</span> <span class="nn">torch._utils_internal</span> <span class="kn">import</span> <span class="n">get_source_lines_and_file</span>
<span class="k">if</span> <span class="n">PY2</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">copy_reg</span> <span class="k">as</span> <span class="nn">copyreg</span>
    <span class="kn">import</span> <span class="nn">cPickle</span> <span class="k">as</span> <span class="nn">pickle</span>
<span class="k">else</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">copyreg</span>
    <span class="kn">import</span> <span class="nn">pickle</span>
    <span class="kn">import</span> <span class="nn">pathlib</span>

<span class="n">DEFAULT_PROTOCOL</span> <span class="o">=</span> <span class="mi">2</span>

<span class="n">LONG_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">Struct</span><span class="p">(</span><span class="s1">&#39;=l&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">size</span>
<span class="n">INT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">Struct</span><span class="p">(</span><span class="s1">&#39;=i&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">size</span>
<span class="n">SHORT_SIZE</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">Struct</span><span class="p">(</span><span class="s1">&#39;=h&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">size</span>

<span class="n">MAGIC_NUMBER</span> <span class="o">=</span> <span class="mh">0x1950a86a20f9469cfc6c</span>
<span class="n">PROTOCOL_VERSION</span> <span class="o">=</span> <span class="mi">1001</span>
<span class="n">STORAGE_KEY_SEPARATOR</span> <span class="o">=</span> <span class="s1">&#39;,&#39;</span>


<span class="k">class</span> <span class="nc">SourceChangeWarning</span><span class="p">(</span><span class="ne">Warning</span><span class="p">):</span>
    <span class="k">pass</span>


<span class="nd">@contextmanager</span>
<span class="k">def</span> <span class="nf">mkdtemp</span><span class="p">():</span>
    <span class="n">path</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">mkdtemp</span><span class="p">()</span>
    <span class="k">yield</span> <span class="n">path</span>
    <span class="n">shutil</span><span class="o">.</span><span class="n">rmtree</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>


<span class="n">_package_registry</span> <span class="o">=</span> <span class="p">[]</span>


<span class="k">def</span> <span class="nf">_is_zipfile</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
    <span class="c1"># This is a stricter implementation than zipfile.is_zipfile().</span>
    <span class="c1"># zipfile.is_zipfile() is True if the magic number appears anywhere in the</span>
    <span class="c1"># binary. Since we expect the files here to be generated by torch.save or</span>
    <span class="c1"># torch.jit.save, it&#39;s safe to only check the start bytes and avoid</span>
    <span class="c1"># collisions and assume the zip has only 1 file.</span>
    <span class="c1"># See bugs.python.org/issue28494.</span>

    <span class="c1"># Read the first 4 bytes of the file</span>
    <span class="n">read_bytes</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">start</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>

    <span class="n">byte</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="k">while</span> <span class="n">byte</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
        <span class="n">read_bytes</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">byte</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">read_bytes</span><span class="p">)</span> <span class="o">==</span> <span class="mi">4</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="n">byte</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">start</span><span class="p">)</span>

    <span class="n">local_header_magic_number</span> <span class="o">=</span> <span class="p">[</span><span class="sa">b</span><span class="s1">&#39;P&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;K&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x03</span><span class="s1">&#39;</span><span class="p">,</span> <span class="sa">b</span><span class="s1">&#39;</span><span class="se">\x04</span><span class="s1">&#39;</span><span class="p">]</span>
    <span class="k">return</span> <span class="n">read_bytes</span> <span class="o">==</span> <span class="n">local_header_magic_number</span>


<span class="k">def</span> <span class="nf">register_package</span><span class="p">(</span><span class="n">priority</span><span class="p">,</span> <span class="n">tagger</span><span class="p">,</span> <span class="n">deserializer</span><span class="p">):</span>
    <span class="n">queue_elem</span> <span class="o">=</span> <span class="p">(</span><span class="n">priority</span><span class="p">,</span> <span class="n">tagger</span><span class="p">,</span> <span class="n">deserializer</span><span class="p">)</span>
    <span class="n">_package_registry</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">queue_elem</span><span class="p">)</span>
    <span class="n">_package_registry</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>


<span class="k">def</span> <span class="nf">check_module_version_greater_or_equal</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">req_version_tuple</span><span class="p">,</span> <span class="n">error_if_malformed</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
    <span class="sd">&#39;&#39;&#39;</span>
<span class="sd">    Check if a module&#39;s version satisfies requirements</span>

<span class="sd">    Usually, a module&#39;s version string will be like &#39;x.y.z&#39;, which would be represented</span>
<span class="sd">    as a tuple (x, y, z), but sometimes it could be an unexpected format. If the version</span>
<span class="sd">    string does not match the given tuple&#39;s format up to the length of the tuple, then</span>
<span class="sd">    error and exit or emit a warning.</span>

<span class="sd">    Args:</span>
<span class="sd">        module: the module to check the version of</span>
<span class="sd">        req_version_tuple: tuple (usually of ints) representing the required version</span>
<span class="sd">        error_if_malformed: whether we should exit if module version string is malformed</span>

<span class="sd">    Returns:</span>
<span class="sd">        requirement_is_met: bool</span>
<span class="sd">    &#39;&#39;&#39;</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">version_strs</span> <span class="o">=</span> <span class="n">module</span><span class="o">.</span><span class="n">__version__</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;.&#39;</span><span class="p">)</span>
        <span class="c1"># Cast module version fields to match the types of the required version</span>
        <span class="n">module_version</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
            <span class="nb">type</span><span class="p">(</span><span class="n">req_field</span><span class="p">)(</span><span class="n">version_strs</span><span class="p">[</span><span class="n">idx</span><span class="p">])</span> <span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">req_field</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">req_version_tuple</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="n">requirement_is_met</span> <span class="o">=</span> <span class="n">module_version</span> <span class="o">&gt;=</span> <span class="n">req_version_tuple</span>

    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="n">message</span> <span class="o">=</span> <span class="p">(</span>
            <span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; module version string is malformed &#39;</span><span class="si">%s</span><span class="s2">&#39; and cannot be compared&quot;</span>
            <span class="s2">&quot; with tuple </span><span class="si">%s</span><span class="s2">&quot;</span>
        <span class="p">)</span> <span class="o">%</span> <span class="p">(</span>
            <span class="n">module</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">module</span><span class="o">.</span><span class="n">__version__</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">req_version_tuple</span><span class="p">)</span>
        <span class="p">)</span>
        <span class="k">if</span> <span class="n">error_if_malformed</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">message</span> <span class="o">+</span> <span class="s1">&#39;, but continuing assuming that requirement is met&#39;</span><span class="p">)</span>
            <span class="n">requirement_is_met</span> <span class="o">=</span> <span class="kc">True</span>

    <span class="k">return</span> <span class="n">requirement_is_met</span>


<span class="k">def</span> <span class="nf">_cpu_tag</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">==</span> <span class="s1">&#39;torch&#39;</span><span class="p">:</span>
        <span class="k">return</span> <span class="s1">&#39;cpu&#39;</span>


<span class="k">def</span> <span class="nf">_cuda_tag</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__module__</span> <span class="o">==</span> <span class="s1">&#39;torch.cuda&#39;</span><span class="p">:</span>
        <span class="k">return</span> <span class="s1">&#39;cuda:&#39;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">get_device</span><span class="p">())</span>


<span class="k">def</span> <span class="nf">_cpu_deserialize</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">location</span> <span class="o">==</span> <span class="s1">&#39;cpu&#39;</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">obj</span>


<span class="k">def</span> <span class="nf">validate_cuda_device</span><span class="p">(</span><span class="n">location</span><span class="p">):</span>
    <span class="n">device</span> <span class="o">=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">_utils</span><span class="o">.</span><span class="n">_get_device_index</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="kc">True</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">is_available</span><span class="p">():</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">&#39;Attempting to deserialize object on a CUDA &#39;</span>
                           <span class="s1">&#39;device but torch.cuda.is_available() is False. &#39;</span>
                           <span class="s1">&#39;If you are running on a CPU-only machine, &#39;</span>
                           <span class="s1">&#39;please use torch.load with map_location=torch.device(</span><span class="se">\&#39;</span><span class="s1">cpu</span><span class="se">\&#39;</span><span class="s1">) &#39;</span>
                           <span class="s1">&#39;to map your storages to the CPU.&#39;</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">device</span> <span class="o">&gt;=</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">device_count</span><span class="p">():</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">&#39;Attempting to deserialize object on CUDA device &#39;</span>
                           <span class="s1">&#39;</span><span class="si">{device}</span><span class="s1"> but torch.cuda.device_count() is </span><span class="si">{device_count}</span><span class="s1">. Please use &#39;</span>
                           <span class="s1">&#39;torch.load with map_location to map your storages &#39;</span>
                           <span class="s1">&#39;to an existing device.&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
                               <span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">,</span> <span class="n">device_count</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">device_count</span><span class="p">()))</span>
    <span class="k">return</span> <span class="n">device</span>


<span class="k">def</span> <span class="nf">_cuda_deserialize</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">location</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;cuda&#39;</span><span class="p">):</span>
        <span class="n">device</span> <span class="o">=</span> <span class="n">validate_cuda_device</span><span class="p">(</span><span class="n">location</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">&quot;_torch_load_uninitialized&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
            <span class="n">storage_type</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
            <span class="k">with</span> <span class="n">torch</span><span class="o">.</span><span class="n">cuda</span><span class="o">.</span><span class="n">device</span><span class="p">(</span><span class="n">device</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">storage_type</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">size</span><span class="p">())</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="n">cuda</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>


<span class="n">register_package</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="n">_cpu_tag</span><span class="p">,</span> <span class="n">_cpu_deserialize</span><span class="p">)</span>
<span class="n">register_package</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="n">_cuda_tag</span><span class="p">,</span> <span class="n">_cuda_deserialize</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">location_tag</span><span class="p">(</span><span class="n">storage</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">tagger</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">_package_registry</span><span class="p">:</span>
        <span class="n">location</span> <span class="o">=</span> <span class="n">tagger</span><span class="p">(</span><span class="n">storage</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">location</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">location</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;don&#39;t know how to determine data location of &quot;</span>
                       <span class="o">+</span> <span class="n">torch</span><span class="o">.</span><span class="n">typename</span><span class="p">(</span><span class="n">storage</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">default_restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">fn</span> <span class="ow">in</span> <span class="n">_package_registry</span><span class="p">:</span>
        <span class="n">result</span> <span class="o">=</span> <span class="n">fn</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">result</span>
    <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;don&#39;t know how to restore data location of &quot;</span>
                       <span class="o">+</span> <span class="n">torch</span><span class="o">.</span><span class="n">typename</span><span class="p">(</span><span class="n">storage</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot; (tagged with &quot;</span>
                       <span class="o">+</span> <span class="n">location</span> <span class="o">+</span> <span class="s2">&quot;)&quot;</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">normalize_storage_type</span><span class="p">(</span><span class="n">storage_type</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">torch</span><span class="p">,</span> <span class="n">storage_type</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">storage_to_tensor_type</span><span class="p">(</span><span class="n">storage</span><span class="p">):</span>
    <span class="n">storage_type</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">storage</span><span class="p">)</span>
    <span class="n">module</span> <span class="o">=</span> <span class="n">_import_dotted_name</span><span class="p">(</span><span class="n">storage_type</span><span class="o">.</span><span class="vm">__module__</span><span class="p">)</span>
    <span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">storage_type</span><span class="o">.</span><span class="vm">__name__</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;Storage&#39;</span><span class="p">,</span> <span class="s1">&#39;Tensor&#39;</span><span class="p">))</span>


<span class="k">def</span> <span class="nf">_is_path</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">):</span>
    <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> \
        <span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">,</span> <span class="n">unicode</span><span class="p">))</span> <span class="ow">or</span> \
        <span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mi">3</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">,</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">))</span>


<span class="k">class</span> <span class="nc">_opener</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file_like</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span> <span class="o">=</span> <span class="n">file_like</span>

    <span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span>

    <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="k">pass</span>


<span class="k">class</span> <span class="nc">_open_file</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">_open_file</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">mode</span><span class="p">))</span>

    <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>


<span class="k">class</span> <span class="nc">_open_buffer_reader</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">_open_buffer_reader</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span>
        <span class="n">_check_seekable</span><span class="p">(</span><span class="n">buffer</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">_open_buffer_writer</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>


<span class="k">def</span> <span class="nf">_open_file_like</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">,</span> <span class="n">mode</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">_is_path</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">_open_file</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">if</span> <span class="s1">&#39;w&#39;</span> <span class="ow">in</span> <span class="n">mode</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">_open_buffer_writer</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">)</span>
        <span class="k">elif</span> <span class="s1">&#39;r&#39;</span> <span class="ow">in</span> <span class="n">mode</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">_open_buffer_reader</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Expected &#39;r&#39; or &#39;w&#39; in mode but got </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mode</span><span class="p">))</span>


<span class="k">class</span> <span class="nc">_open_zipfile_reader</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name_or_buffer</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">_open_zipfile_reader</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">_C</span><span class="o">.</span><span class="n">PyTorchFileReader</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">))</span>


<span class="k">class</span> <span class="nc">_open_zipfile_writer_file</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">_open_zipfile_writer_file</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">_C</span><span class="o">.</span><span class="n">PyTorchFileWriter</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>

    <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span><span class="o">.</span><span class="n">write_end_of_file</span><span class="p">()</span>


<span class="k">class</span> <span class="nc">_open_zipfile_writer_buffer</span><span class="p">(</span><span class="n">_opener</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">buffer</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">buffer</span> <span class="o">=</span> <span class="n">buffer</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">_open_zipfile_writer_buffer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">_C</span><span class="o">.</span><span class="n">PyTorchFileWriter</span><span class="p">(</span><span class="n">buffer</span><span class="p">))</span>

    <span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">file_like</span><span class="o">.</span><span class="n">write_end_of_file</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">buffer</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>


<span class="k">def</span> <span class="nf">_open_zipfile_writer</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">_is_path</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">):</span>
        <span class="n">container</span> <span class="o">=</span> <span class="n">_open_zipfile_writer_file</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">container</span> <span class="o">=</span> <span class="n">_open_zipfile_writer_buffer</span>
    <span class="k">return</span> <span class="n">container</span><span class="p">(</span><span class="n">name_or_buffer</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">_is_compressed_file</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
    <span class="n">compress_modules</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;gzip&#39;</span><span class="p">]</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="vm">__module__</span> <span class="ow">in</span> <span class="n">compress_modules</span>
    <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>


<span class="k">def</span> <span class="nf">_should_read_directly</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Checks if f is a file that should be read directly. It should be read</span>
<span class="sd">    directly if it is backed by a real file (has a fileno) and is not a</span>
<span class="sd">    a compressed file (e.g. gzip)</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">_is_compressed_file</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">fileno</span><span class="p">()</span> <span class="o">&gt;=</span> <span class="mi">0</span>
    <span class="k">except</span> <span class="n">io</span><span class="o">.</span><span class="n">UnsupportedOperation</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>
    <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
        <span class="k">return</span> <span class="kc">False</span>


<span class="k">def</span> <span class="nf">_check_seekable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">raise_err_msg</span><span class="p">(</span><span class="n">patterns</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">patterns</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">):</span>
                <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&quot;. You can only torch.load from a file that is seekable.&quot;</span>
                                <span class="o">+</span> <span class="s2">&quot; Please pre-load the data into a buffer like io.BytesIO and&quot;</span>
                                <span class="o">+</span> <span class="s2">&quot; try to load from it instead.&quot;</span><span class="p">)</span>
                <span class="k">raise</span> <span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)(</span><span class="n">msg</span><span class="p">)</span>
        <span class="k">raise</span> <span class="n">e</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">())</span>
        <span class="k">return</span> <span class="kc">True</span>
    <span class="k">except</span> <span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">UnsupportedOperation</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">)</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
        <span class="n">raise_err_msg</span><span class="p">([</span><span class="s2">&quot;seek&quot;</span><span class="p">,</span> <span class="s2">&quot;tell&quot;</span><span class="p">],</span> <span class="n">e</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">_check_dill_version</span><span class="p">(</span><span class="n">pickle_module</span><span class="p">):</span>
    <span class="sd">&#39;&#39;&#39;Checks if using dill as the pickle module, and if so, checks if it is the correct version.</span>
<span class="sd">    If dill version is lower than 0.3.1, a ValueError is raised.</span>

<span class="sd">    Args:</span>
<span class="sd">        pickle_module: module used for pickling metadata and objects</span>

<span class="sd">    &#39;&#39;&#39;</span>
    <span class="k">if</span> <span class="n">pickle_module</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;dill&#39;</span><span class="p">:</span>
        <span class="n">required_dill_version</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">check_module_version_greater_or_equal</span><span class="p">(</span><span class="n">pickle_module</span><span class="p">,</span> <span class="n">required_dill_version</span><span class="p">,</span> <span class="kc">False</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">((</span>
                <span class="s2">&quot;&#39;torch&#39; supports dill &gt;= </span><span class="si">%s</span><span class="s2">, but you have dill </span><span class="si">%s</span><span class="s2">.&quot;</span>
                <span class="s2">&quot; Please upgrade dill or switch to &#39;pickle&#39;&quot;</span>
            <span class="p">)</span> <span class="o">%</span> <span class="p">(</span>
                <span class="s1">&#39;.&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">num</span><span class="p">)</span> <span class="k">for</span> <span class="n">num</span> <span class="ow">in</span> <span class="n">required_dill_version</span><span class="p">]),</span>
                <span class="n">pickle_module</span><span class="o">.</span><span class="n">__version__</span>
            <span class="p">))</span>

<div class="viewcode-block" id="save"><a class="viewcode-back" href="../../torch.html#torch.save">[docs]</a><span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">pickle_module</span><span class="o">=</span><span class="n">pickle</span><span class="p">,</span> <span class="n">pickle_protocol</span><span class="o">=</span><span class="n">DEFAULT_PROTOCOL</span><span class="p">,</span> <span class="n">_use_new_zipfile_serialization</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Saves an object to a disk file.</span>

<span class="sd">    See also: :ref:`recommend-saving-models`</span>

<span class="sd">    Args:</span>
<span class="sd">        obj: saved object</span>
<span class="sd">        f: a file-like object (has to implement write and flush) or a string</span>
<span class="sd">           containing a file name</span>
<span class="sd">        pickle_module: module used for pickling metadata and objects</span>
<span class="sd">        pickle_protocol: can be specified to override the default protocol</span>

<span class="sd">    .. warning::</span>
<span class="sd">        If you are using Python 2, :func:`torch.save` does NOT support :class:`StringIO.StringIO`</span>
<span class="sd">        as a valid file-like object. This is because the write method should return</span>
<span class="sd">        the number of bytes written; :meth:`StringIO.write()` does not do this.</span>

<span class="sd">        Please use something like :class:`io.BytesIO` instead.</span>

<span class="sd">    Example:</span>
<span class="sd">        &gt;&gt;&gt; # Save to file</span>
<span class="sd">        &gt;&gt;&gt; x = torch.tensor([0, 1, 2, 3, 4])</span>
<span class="sd">        &gt;&gt;&gt; torch.save(x, &#39;tensor.pt&#39;)</span>
<span class="sd">        &gt;&gt;&gt; # Save to io.BytesIO buffer</span>
<span class="sd">        &gt;&gt;&gt; buffer = io.BytesIO()</span>
<span class="sd">        &gt;&gt;&gt; torch.save(x, buffer)</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">_check_dill_version</span><span class="p">(</span><span class="n">pickle_module</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">_use_new_zipfile_serialization</span><span class="p">:</span>
        <span class="k">with</span> <span class="n">_open_zipfile_writer</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">as</span> <span class="n">opened_file</span><span class="p">:</span>
            <span class="n">_save</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">opened_file</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="n">pickle_protocol</span><span class="p">)</span>
            <span class="k">return</span>

    <span class="k">with</span> <span class="n">_open_file_like</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">opened_file</span><span class="p">:</span>
        <span class="n">_legacy_save</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">opened_file</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="n">pickle_protocol</span><span class="p">)</span></div>


<span class="k">def</span> <span class="nf">_legacy_save</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="n">pickle_protocol</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
        <span class="kn">import</span> <span class="nn">StringIO</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">StringIO</span><span class="o">.</span><span class="n">StringIO</span><span class="p">):</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;torch.save received unsupported StringIO.StringIO file object, whose &#39;</span>
                   <span class="s1">&#39;write method does not return the number of bytes written. &#39;</span>
                   <span class="s1">&#39;Please use something like io.BytesIO for torch.save instead.&#39;</span><span class="p">)</span>
            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>

    <span class="kn">import</span> <span class="nn">torch.nn</span> <span class="k">as</span> <span class="nn">nn</span>
    <span class="n">serialized_container_types</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">serialized_storages</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">persistent_id</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
        <span class="c1"># FIXME: the docs say that persistent_id should only return a string</span>
        <span class="c1"># but torch store returns tuples. This works only in the binary protocol</span>
        <span class="c1"># see</span>
        <span class="c1"># https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-external-objects</span>
        <span class="c1"># https://github.com/python/cpython/blob/master/Lib/pickle.py#L527-L537</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">type</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">nn</span><span class="o">.</span><span class="n">Module</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">serialized_container_types</span><span class="p">:</span>
                <span class="k">return</span> <span class="kc">None</span>
            <span class="n">serialized_container_types</span><span class="p">[</span><span class="n">obj</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
            <span class="n">source_file</span> <span class="o">=</span> <span class="n">source</span> <span class="o">=</span> <span class="kc">None</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">source_lines</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">source_file</span> <span class="o">=</span> <span class="n">get_source_lines_and_file</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
                <span class="n">source</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">source_lines</span><span class="p">)</span>
            <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>  <span class="c1"># saving the source is optional, so we can ignore any errors</span>
                <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;Couldn&#39;t retrieve source code for container of &quot;</span>
                              <span class="s2">&quot;type &quot;</span> <span class="o">+</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">+</span> <span class="s2">&quot;. It won&#39;t be checked &quot;</span>
                              <span class="s2">&quot;for correctness upon loading.&quot;</span><span class="p">)</span>
            <span class="k">return</span> <span class="p">(</span><span class="s1">&#39;module&#39;</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">source_file</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span>

        <span class="k">elif</span> <span class="n">torch</span><span class="o">.</span><span class="n">is_storage</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
            <span class="n">storage_type</span> <span class="o">=</span> <span class="n">normalize_storage_type</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
            <span class="c1"># Offset is always 0, but we keep it for backwards compatibility</span>
            <span class="c1"># with the old serialization format (which supported storage views)</span>
            <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span>
            <span class="n">obj_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">_cdata</span><span class="p">)</span>
            <span class="n">location</span> <span class="o">=</span> <span class="n">location_tag</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
            <span class="n">serialized_storages</span><span class="p">[</span><span class="n">obj_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>
            <span class="n">is_view</span> <span class="o">=</span> <span class="n">obj</span><span class="o">.</span><span class="n">_cdata</span> <span class="o">!=</span> <span class="n">obj</span><span class="o">.</span><span class="n">_cdata</span>
            <span class="k">if</span> <span class="n">is_view</span><span class="p">:</span>
                <span class="n">view_metadata</span> <span class="o">=</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">_cdata</span><span class="p">),</span> <span class="n">offset</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">size</span><span class="p">())</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">view_metadata</span> <span class="o">=</span> <span class="kc">None</span>

            <span class="k">return</span> <span class="p">(</span><span class="s1">&#39;storage&#39;</span><span class="p">,</span>
                    <span class="n">storage_type</span><span class="p">,</span>
                    <span class="n">obj_key</span><span class="p">,</span>
                    <span class="n">location</span><span class="p">,</span>
                    <span class="n">obj</span><span class="o">.</span><span class="n">size</span><span class="p">(),</span>
                    <span class="n">view_metadata</span><span class="p">)</span>
        <span class="k">return</span> <span class="kc">None</span>

    <span class="n">sys_info</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
        <span class="n">protocol_version</span><span class="o">=</span><span class="n">PROTOCOL_VERSION</span><span class="p">,</span>
        <span class="n">little_endian</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">byteorder</span> <span class="o">==</span> <span class="s1">&#39;little&#39;</span><span class="p">,</span>
        <span class="n">type_sizes</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span>
            <span class="n">short</span><span class="o">=</span><span class="n">SHORT_SIZE</span><span class="p">,</span>
            <span class="nb">int</span><span class="o">=</span><span class="n">INT_SIZE</span><span class="p">,</span>
            <span class="n">long</span><span class="o">=</span><span class="n">LONG_SIZE</span><span class="p">,</span>
        <span class="p">),</span>
    <span class="p">)</span>

    <span class="n">pickle_module</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">MAGIC_NUMBER</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">pickle_module</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">PROTOCOL_VERSION</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">pickle_module</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">sys_info</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">pickler</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">Pickler</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">pickler</span><span class="o">.</span><span class="n">persistent_id</span> <span class="o">=</span> <span class="n">persistent_id</span>
    <span class="n">pickler</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>

    <span class="n">serialized_storage_keys</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">serialized_storages</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
    <span class="n">pickle_module</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">serialized_storage_keys</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">f</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
    <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">serialized_storage_keys</span><span class="p">:</span>
        <span class="n">serialized_storages</span><span class="p">[</span><span class="n">key</span><span class="p">]</span><span class="o">.</span><span class="n">_write_file</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">_should_read_directly</span><span class="p">(</span><span class="n">f</span><span class="p">),</span> <span class="kc">True</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">_save</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">zip_file</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="n">pickle_protocol</span><span class="p">):</span>
    <span class="n">serialized_storages</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">persistent_id</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
        <span class="c1"># FIXME: the docs say that persistent_id should only return a string</span>
        <span class="c1"># but torch store returns tuples. This works only in the binary protocol</span>
        <span class="c1"># see</span>
        <span class="c1"># https://docs.python.org/2/library/pickle.html#pickling-and-unpickling-external-objects</span>
        <span class="c1"># https://github.com/python/cpython/blob/master/Lib/pickle.py#L527-L537</span>
        <span class="k">if</span> <span class="n">torch</span><span class="o">.</span><span class="n">is_storage</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
            <span class="n">storage_type</span> <span class="o">=</span> <span class="n">normalize_storage_type</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">))</span>
            <span class="n">obj_key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">_cdata</span><span class="p">)</span>
            <span class="n">location</span> <span class="o">=</span> <span class="n">location_tag</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
            <span class="n">serialized_storages</span><span class="p">[</span><span class="n">obj_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>

            <span class="k">return</span> <span class="p">(</span><span class="s1">&#39;storage&#39;</span><span class="p">,</span>
                    <span class="n">storage_type</span><span class="p">,</span>
                    <span class="n">obj_key</span><span class="p">,</span>
                    <span class="n">location</span><span class="p">,</span>
                    <span class="n">obj</span><span class="o">.</span><span class="n">size</span><span class="p">())</span>
        <span class="k">return</span> <span class="kc">None</span>

    <span class="c1"># Write the pickle data for `obj`</span>
    <span class="n">data_buf</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
    <span class="n">pickler</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">Pickler</span><span class="p">(</span><span class="n">data_buf</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="n">pickle_protocol</span><span class="p">)</span>
    <span class="n">pickler</span><span class="o">.</span><span class="n">persistent_id</span> <span class="o">=</span> <span class="n">persistent_id</span>
    <span class="n">pickler</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
    <span class="n">data_value</span> <span class="o">=</span> <span class="n">data_buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
    <span class="n">zip_file</span><span class="o">.</span><span class="n">write_record</span><span class="p">(</span><span class="s1">&#39;data.pkl&#39;</span><span class="p">,</span> <span class="n">data_value</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data_value</span><span class="p">))</span>

    <span class="c1"># Write each tensor to a file named tensor/the_tensor_key in the zip archive</span>
    <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">serialized_storages</span><span class="o">.</span><span class="n">keys</span><span class="p">()):</span>
        <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;data/</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
        <span class="n">storage</span> <span class="o">=</span> <span class="n">serialized_storages</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
        <span class="k">if</span> <span class="n">storage</span><span class="o">.</span><span class="n">device</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s1">&#39;cpu&#39;</span><span class="p">:</span>
            <span class="c1"># If it&#39;s on the CPU we can directly copy it into the zip file</span>
            <span class="n">num_bytes</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">size</span><span class="p">()</span> <span class="o">*</span> <span class="n">storage</span><span class="o">.</span><span class="n">element_size</span><span class="p">()</span>
            <span class="n">buf</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
            <span class="n">zip_file</span><span class="o">.</span><span class="n">write_record</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">storage</span><span class="o">.</span><span class="n">data_ptr</span><span class="p">(),</span> <span class="n">num_bytes</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Copy to a buffer, then serialize that</span>
            <span class="n">buf</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span>
            <span class="n">storage</span><span class="o">.</span><span class="n">_write_file</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">_should_read_directly</span><span class="p">(</span><span class="n">buf</span><span class="p">))</span>
            <span class="n">buf_value</span> <span class="o">=</span> <span class="n">buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
            <span class="n">zip_file</span><span class="o">.</span><span class="n">write_record</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">buf_value</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">buf_value</span><span class="p">))</span>


<div class="viewcode-block" id="load"><a class="viewcode-back" href="../../torch.html#torch.load">[docs]</a><span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">map_location</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pickle_module</span><span class="o">=</span><span class="n">pickle</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Loads an object saved with :func:`torch.save` from a file.</span>

<span class="sd">    :func:`torch.load` uses Python&#39;s unpickling facilities but treats storages,</span>
<span class="sd">    which underlie tensors, specially. They are first deserialized on the</span>
<span class="sd">    CPU and are then moved to the device they were saved from. If this fails</span>
<span class="sd">    (e.g. because the run time system doesn&#39;t have certain devices), an exception</span>
<span class="sd">    is raised. However, storages can be dynamically remapped to an alternative</span>
<span class="sd">    set of devices using the :attr:`map_location` argument.</span>

<span class="sd">    If :attr:`map_location` is a callable, it will be called once for each serialized</span>
<span class="sd">    storage with two arguments: storage and location. The storage argument</span>
<span class="sd">    will be the initial deserialization of the storage, residing on the CPU.</span>
<span class="sd">    Each serialized storage has a location tag associated with it which</span>
<span class="sd">    identifies the device it was saved from, and this tag is the second</span>
<span class="sd">    argument passed to :attr:`map_location`. The builtin location tags are ``&#39;cpu&#39;``</span>
<span class="sd">    for CPU tensors and ``&#39;cuda:device_id&#39;`` (e.g. ``&#39;cuda:2&#39;``) for CUDA tensors.</span>
<span class="sd">    :attr:`map_location` should return either ``None`` or a storage. If</span>
<span class="sd">    :attr:`map_location` returns a storage, it will be used as the final deserialized</span>
<span class="sd">    object, already moved to the right device. Otherwise, :func:`torch.load` will</span>
<span class="sd">    fall back to the default behavior, as if :attr:`map_location` wasn&#39;t specified.</span>

<span class="sd">    If :attr:`map_location` is a :class:`torch.device` object or a string containing</span>
<span class="sd">    a device tag, it indicates the location where all tensors should be loaded.</span>

<span class="sd">    Otherwise, if :attr:`map_location` is a dict, it will be used to remap location tags</span>
<span class="sd">    appearing in the file (keys), to ones that specify where to put the</span>
<span class="sd">    storages (values).</span>

<span class="sd">    User extensions can register their own location tags and tagging and</span>
<span class="sd">    deserialization methods using :func:`torch.serialization.register_package`.</span>

<span class="sd">    Args:</span>
<span class="sd">        f: a file-like object (has to implement :meth:`read`, :meth`readline`, :meth`tell`, and :meth`seek`),</span>
<span class="sd">            or a string containing a file name</span>
<span class="sd">        map_location: a function, :class:`torch.device`, string or a dict specifying how to remap storage</span>
<span class="sd">            locations</span>
<span class="sd">        pickle_module: module used for unpickling metadata and objects (has to</span>
<span class="sd">            match the :attr:`pickle_module` used to serialize file)</span>
<span class="sd">        pickle_load_args: (Python 3 only) optional keyword arguments passed over to</span>
<span class="sd">            :func:`pickle_module.load` and :func:`pickle_module.Unpickler`, e.g.,</span>
<span class="sd">            :attr:`errors=...`.</span>

<span class="sd">    .. warning::</span>
<span class="sd">        :func:`torch.load()` uses ``pickle`` module implicitly, which is known to be insecure.</span>
<span class="sd">        It is possible to construct malicious pickle data which will execute arbitrary code</span>
<span class="sd">        during unpickling. Never load data that could have come from an untrusted</span>
<span class="sd">        source, or that could have been tampered with. **Only load data you trust**.</span>

<span class="sd">    .. note::</span>
<span class="sd">        When you call :func:`torch.load()` on a file which contains GPU tensors, those tensors</span>
<span class="sd">        will be loaded to GPU by default. You can call ``torch.load(.., map_location=&#39;cpu&#39;)``</span>
<span class="sd">        and then :meth:`load_state_dict` to avoid GPU RAM surge when loading a model checkpoint.</span>

<span class="sd">    .. note::</span>
<span class="sd">        By default, we decode byte strings as ``utf-8``.  This is to avoid a common error</span>
<span class="sd">        case ``UnicodeDecodeError: &#39;ascii&#39; codec can&#39;t decode byte 0x...``</span>
<span class="sd">        when loading files saved by Python 2 in Python 3.  If this default</span>
<span class="sd">        is incorrect, you may use an extra :attr:`encoding` keyword argument to specify how</span>
<span class="sd">        these objects should be loaded, e.g., :attr:`encoding=&#39;latin1&#39;` decodes them</span>
<span class="sd">        to strings using ``latin1`` encoding, and :attr:`encoding=&#39;bytes&#39;` keeps them</span>
<span class="sd">        as byte arrays which can be decoded later with ``byte_array.decode(...)``.</span>

<span class="sd">    Example:</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;tensors.pt&#39;)</span>
<span class="sd">        # Load all tensors onto the CPU</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;tensors.pt&#39;, map_location=torch.device(&#39;cpu&#39;))</span>
<span class="sd">        # Load all tensors onto the CPU, using a function</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;tensors.pt&#39;, map_location=lambda storage, loc: storage)</span>
<span class="sd">        # Load all tensors onto GPU 1</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;tensors.pt&#39;, map_location=lambda storage, loc: storage.cuda(1))</span>
<span class="sd">        # Map tensors from GPU 1 to GPU 0</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;tensors.pt&#39;, map_location={&#39;cuda:1&#39;:&#39;cuda:0&#39;})</span>
<span class="sd">        # Load tensor from io.BytesIO object</span>
<span class="sd">        &gt;&gt;&gt; with open(&#39;tensor.pt&#39;, &#39;rb&#39;) as f:</span>
<span class="sd">                buffer = io.BytesIO(f.read())</span>
<span class="sd">        &gt;&gt;&gt; torch.load(buffer)</span>
<span class="sd">        # Load a module with &#39;ascii&#39; encoding for unpickling</span>
<span class="sd">        &gt;&gt;&gt; torch.load(&#39;module.pt&#39;, encoding=&#39;ascii&#39;)</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">_check_dill_version</span><span class="p">(</span><span class="n">pickle_module</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="s1">&#39;encoding&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">pickle_load_args</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
        <span class="n">pickle_load_args</span><span class="p">[</span><span class="s1">&#39;encoding&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;utf-8&#39;</span>

    <span class="k">with</span> <span class="n">_open_file_like</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">opened_file</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">_is_zipfile</span><span class="p">(</span><span class="n">opened_file</span><span class="p">):</span>
            <span class="k">with</span> <span class="n">_open_zipfile_reader</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">as</span> <span class="n">opened_zipfile</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">_is_torchscript_zip</span><span class="p">(</span><span class="n">opened_zipfile</span><span class="p">):</span>
                    <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;&#39;torch.load&#39; received a zip file that looks like a TorchScript archive&quot;</span>
                                  <span class="s2">&quot; dispatching to &#39;torch.jit.load&#39; (call &#39;torch.jit.load&#39; directly to&quot;</span>
                                  <span class="s2">&quot; silence this warning)&quot;</span><span class="p">,</span> <span class="ne">UserWarning</span><span class="p">)</span>
                    <span class="k">return</span> <span class="n">torch</span><span class="o">.</span><span class="n">jit</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">_load</span><span class="p">(</span><span class="n">opened_zipfile</span><span class="p">,</span> <span class="n">map_location</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">_legacy_load</span><span class="p">(</span><span class="n">opened_file</span><span class="p">,</span> <span class="n">map_location</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span></div>


<span class="c1"># Register pickling support for layout instances such as</span>
<span class="c1"># torch.sparse_coo, etc</span>
<span class="k">def</span> <span class="nf">_get_layout</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Get layout extension object from its string representation.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">cache</span> <span class="o">=</span> <span class="n">_get_layout</span><span class="o">.</span><span class="n">cache</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">cache</span><span class="p">:</span>
        <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">torch</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">torch</span><span class="o">.</span><span class="n">layout</span><span class="p">):</span>
                <span class="n">cache</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">v</span><span class="p">)]</span> <span class="o">=</span> <span class="n">v</span>
    <span class="k">return</span> <span class="n">cache</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>


<span class="n">_get_layout</span><span class="o">.</span><span class="n">cache</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">copyreg</span><span class="o">.</span><span class="n">pickle</span><span class="p">(</span><span class="n">torch</span><span class="o">.</span><span class="n">layout</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">obj</span><span class="p">:</span> <span class="p">(</span><span class="n">_get_layout</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="p">),)))</span>


<span class="k">def</span> <span class="nf">_legacy_load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">map_location</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">):</span>
    <span class="n">deserialized_objects</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="n">restore_location</span> <span class="o">=</span> <span class="n">_get_restore_location</span><span class="p">(</span><span class="n">map_location</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_check_container_source</span><span class="p">(</span><span class="n">container_type</span><span class="p">,</span> <span class="n">source_file</span><span class="p">,</span> <span class="n">original_source</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">current_source</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">get_source_lines_and_file</span><span class="p">(</span><span class="n">container_type</span><span class="p">)[</span><span class="mi">0</span><span class="p">])</span>
        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>  <span class="c1"># saving the source is optional, so we can ignore any errors</span>
            <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;Couldn&#39;t retrieve source code for container of &quot;</span>
                          <span class="s2">&quot;type &quot;</span> <span class="o">+</span> <span class="n">container_type</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">+</span> <span class="s2">&quot;. It won&#39;t be checked &quot;</span>
                          <span class="s2">&quot;for correctness upon loading.&quot;</span><span class="p">)</span>
            <span class="k">return</span>
        <span class="k">if</span> <span class="n">original_source</span> <span class="o">!=</span> <span class="n">current_source</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">container_type</span><span class="o">.</span><span class="n">dump_patches</span><span class="p">:</span>
                <span class="n">file_name</span> <span class="o">=</span> <span class="n">container_type</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">+</span> <span class="s1">&#39;.patch&#39;</span>
                <span class="n">diff</span> <span class="o">=</span> <span class="n">difflib</span><span class="o">.</span><span class="n">unified_diff</span><span class="p">(</span><span class="n">current_source</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">),</span>
                                            <span class="n">original_source</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">),</span>
                                            <span class="n">source_file</span><span class="p">,</span>
                                            <span class="n">source_file</span><span class="p">,</span> <span class="n">lineterm</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
                <span class="n">lines</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">diff</span><span class="p">)</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="s1">&#39;a+&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                        <span class="n">file_size</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
                        <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
                        <span class="k">if</span> <span class="n">file_size</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
                            <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
                        <span class="k">elif</span> <span class="n">file_size</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span> <span class="ow">or</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="o">!=</span> <span class="n">lines</span><span class="p">:</span>
                            <span class="k">raise</span> <span class="ne">IOError</span>
                    <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;Saved a reverse patch to &quot;</span> <span class="o">+</span> <span class="n">file_name</span> <span class="o">+</span> <span class="s2">&quot;. &quot;</span>
                           <span class="s2">&quot;Run `patch -p0 &lt; &quot;</span> <span class="o">+</span> <span class="n">file_name</span> <span class="o">+</span> <span class="s2">&quot;` to revert your &quot;</span>
                           <span class="s2">&quot;changes.&quot;</span><span class="p">)</span>
                <span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
                    <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;Tried to save a patch, but couldn&#39;t create a &quot;</span>
                           <span class="s2">&quot;writable file &quot;</span> <span class="o">+</span> <span class="n">file_name</span> <span class="o">+</span> <span class="s2">&quot;. Make sure it &quot;</span>
                           <span class="s2">&quot;doesn&#39;t exist and your working directory is &quot;</span>
                           <span class="s2">&quot;writable.&quot;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;you can retrieve the original source code by &quot;</span>
                       <span class="s2">&quot;accessing the object&#39;s source attribute or set &quot;</span>
                       <span class="s2">&quot;`torch.nn.Module.dump_patches = True` and use the &quot;</span>
                       <span class="s2">&quot;patch tool to revert the changes.&quot;</span><span class="p">)</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;source code of class &#39;</span><span class="si">{container_type}</span><span class="s2">&#39; has changed. </span><span class="si">{msg}</span><span class="s2">&quot;</span>
                   <span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">container_type</span><span class="o">=</span><span class="n">torch</span><span class="o">.</span><span class="n">typename</span><span class="p">(</span><span class="n">container_type</span><span class="p">),</span> <span class="n">msg</span><span class="o">=</span><span class="n">msg</span><span class="p">))</span>
            <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">SourceChangeWarning</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">legacy_load</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
        <span class="n">deserialized_objects</span> <span class="o">=</span> <span class="p">{}</span>

        <span class="k">def</span> <span class="nf">persistent_load</span><span class="p">(</span><span class="n">saved_id</span><span class="p">):</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">saved_id</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
                <span class="c1"># Ignore containers that don&#39;t have any sources saved</span>
                <span class="k">if</span> <span class="nb">all</span><span class="p">(</span><span class="n">saved_id</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
                    <span class="n">_check_container_source</span><span class="p">(</span><span class="o">*</span><span class="n">saved_id</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">saved_id</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="k">return</span> <span class="n">deserialized_objects</span><span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">saved_id</span><span class="p">)]</span>

        <span class="k">with</span> <span class="n">closing</span><span class="p">(</span><span class="n">tarfile</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">fileobj</span><span class="o">=</span><span class="n">f</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;r:&#39;</span><span class="p">,</span> <span class="nb">format</span><span class="o">=</span><span class="n">tarfile</span><span class="o">.</span><span class="n">PAX_FORMAT</span><span class="p">))</span> <span class="k">as</span> <span class="n">tar</span><span class="p">,</span> \
                <span class="n">mkdtemp</span><span class="p">()</span> <span class="k">as</span> <span class="n">tmpdir</span><span class="p">:</span>

            <span class="n">tar</span><span class="o">.</span><span class="n">extract</span><span class="p">(</span><span class="s1">&#39;storages&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="n">tmpdir</span><span class="p">)</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tmpdir</span><span class="p">,</span> <span class="s1">&#39;storages&#39;</span><span class="p">),</span> <span class="s1">&#39;rb&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">num_storages</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
                <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_storages</span><span class="p">):</span>
                    <span class="n">args</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
                    <span class="n">key</span><span class="p">,</span> <span class="n">location</span><span class="p">,</span> <span class="n">storage_type</span> <span class="o">=</span> <span class="n">args</span>
                    <span class="n">obj</span> <span class="o">=</span> <span class="n">storage_type</span><span class="o">.</span><span class="n">_new_with_file</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
                    <span class="n">obj</span> <span class="o">=</span> <span class="n">restore_location</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
                    <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">obj</span>

                <span class="n">storage_views</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
                <span class="k">for</span> <span class="n">target_cdata</span><span class="p">,</span> <span class="n">root_cdata</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">size</span> <span class="ow">in</span> <span class="n">storage_views</span><span class="p">:</span>
                    <span class="n">root</span> <span class="o">=</span> <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">root_cdata</span><span class="p">]</span>
                    <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">target_cdata</span><span class="p">]</span> <span class="o">=</span> <span class="n">root</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span> <span class="o">+</span> <span class="n">size</span><span class="p">]</span>

            <span class="n">tar</span><span class="o">.</span><span class="n">extract</span><span class="p">(</span><span class="s1">&#39;tensors&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="n">tmpdir</span><span class="p">)</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tmpdir</span><span class="p">,</span> <span class="s1">&#39;tensors&#39;</span><span class="p">),</span> <span class="s1">&#39;rb&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">num_tensors</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
                <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_tensors</span><span class="p">):</span>
                    <span class="n">args</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
                    <span class="n">key</span><span class="p">,</span> <span class="n">storage_id</span><span class="p">,</span> <span class="n">original_tensor_type</span> <span class="o">=</span> <span class="n">args</span>
                    <span class="n">storage</span> <span class="o">=</span> <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">storage_id</span><span class="p">]</span>
                    <span class="n">tensor_type</span> <span class="o">=</span> <span class="n">storage_to_tensor_type</span><span class="p">(</span><span class="n">storage</span><span class="p">)</span>
                    <span class="n">ndim</span><span class="p">,</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;i&#39;</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
                    <span class="c1"># skip next 4 bytes; legacy encoding treated ndim as 8 bytes</span>
                    <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
                    <span class="n">size</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;</span><span class="si">{}</span><span class="s1">q&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">ndim</span><span class="p">),</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">8</span> <span class="o">*</span> <span class="n">ndim</span><span class="p">))</span>
                    <span class="n">stride</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;</span><span class="si">{}</span><span class="s1">q&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">ndim</span><span class="p">),</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">8</span> <span class="o">*</span> <span class="n">ndim</span><span class="p">))</span>
                    <span class="n">storage_offset</span><span class="p">,</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s1">&#39;&lt;q&#39;</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">8</span><span class="p">))</span>
                    <span class="n">tensor</span> <span class="o">=</span> <span class="n">tensor_type</span><span class="p">()</span><span class="o">.</span><span class="n">set_</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">storage_offset</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">stride</span><span class="p">)</span>
                    <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">tensor</span>

            <span class="n">pickle_file</span> <span class="o">=</span> <span class="n">tar</span><span class="o">.</span><span class="n">extractfile</span><span class="p">(</span><span class="s1">&#39;pickle&#39;</span><span class="p">)</span>
            <span class="n">unpickler</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">Unpickler</span><span class="p">(</span><span class="n">pickle_file</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
            <span class="n">unpickler</span><span class="o">.</span><span class="n">persistent_load</span> <span class="o">=</span> <span class="n">persistent_load</span>
            <span class="n">result</span> <span class="o">=</span> <span class="n">unpickler</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
            <span class="k">return</span> <span class="n">result</span>

    <span class="n">deserialized_objects</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">persistent_load</span><span class="p">(</span><span class="n">saved_id</span><span class="p">):</span>
        <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">saved_id</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
        <span class="n">typename</span> <span class="o">=</span> <span class="n">_maybe_decode_ascii</span><span class="p">(</span><span class="n">saved_id</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="n">data</span> <span class="o">=</span> <span class="n">saved_id</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>

        <span class="k">if</span> <span class="n">typename</span> <span class="o">==</span> <span class="s1">&#39;module&#39;</span><span class="p">:</span>
            <span class="c1"># Ignore containers that don&#39;t have any sources saved</span>
            <span class="k">if</span> <span class="nb">all</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
                <span class="n">_check_container_source</span><span class="p">(</span><span class="o">*</span><span class="n">data</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="k">elif</span> <span class="n">typename</span> <span class="o">==</span> <span class="s1">&#39;storage&#39;</span><span class="p">:</span>
            <span class="n">data_type</span><span class="p">,</span> <span class="n">root_key</span><span class="p">,</span> <span class="n">location</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">view_metadata</span> <span class="o">=</span> <span class="n">data</span>
            <span class="n">location</span> <span class="o">=</span> <span class="n">_maybe_decode_ascii</span><span class="p">(</span><span class="n">location</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">root_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">deserialized_objects</span><span class="p">:</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="n">data_type</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
                <span class="n">obj</span><span class="o">.</span><span class="n">_torch_load_uninitialized</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">root_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">restore_location</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
            <span class="n">storage</span> <span class="o">=</span> <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">root_key</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">view_metadata</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">view_key</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">view_size</span> <span class="o">=</span> <span class="n">view_metadata</span>
                <span class="k">if</span> <span class="n">view_key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">deserialized_objects</span><span class="p">:</span>
                    <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">view_key</span><span class="p">]</span> <span class="o">=</span> <span class="n">storage</span><span class="p">[</span><span class="n">offset</span><span class="p">:</span><span class="n">offset</span> <span class="o">+</span> <span class="n">view_size</span><span class="p">]</span>
                <span class="k">return</span> <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">view_key</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">storage</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Unknown saved id type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">saved_id</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

    <span class="n">_check_seekable</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
    <span class="n">f_should_read_directly</span> <span class="o">=</span> <span class="n">_should_read_directly</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">f_should_read_directly</span> <span class="ow">and</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="c1"># legacy_load requires that f has fileno()</span>
        <span class="c1"># only if offset is zero we can attempt the legacy tar file loader</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">legacy_load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
        <span class="k">except</span> <span class="n">tarfile</span><span class="o">.</span><span class="n">TarError</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">_is_zipfile</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
                <span class="c1"># .zip is used for torch.jit.save and will throw an un-pickling error here</span>
                <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span>
                    <span class="s2">&quot;</span><span class="si">{filename}</span><span class="s2"> is a zip archive (did you mean to use torch.jit.load()?)&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
            <span class="c1"># if not a tarfile, reset file offset and proceed</span>
            <span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s1">&#39;readinto&#39;</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span> <span class="o">&lt;</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">2</span><span class="p">):</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span>
            <span class="s2">&quot;torch.load does not work with file-like objects that do not implement readinto on Python 3.8.0 and 3.8.1. &quot;</span>
            <span class="s2">&quot;Received object of type </span><span class="se">\&quot;</span><span class="si">{}</span><span class="se">\&quot;</span><span class="s2">. Please update to Python 3.8.2 or newer to restore this &quot;</span>
            <span class="s2">&quot;functionality.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">f</span><span class="p">)))</span>

    <span class="n">magic_number</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">magic_number</span> <span class="o">!=</span> <span class="n">MAGIC_NUMBER</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Invalid magic number; corrupt file?&quot;</span><span class="p">)</span>
    <span class="n">protocol_version</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">protocol_version</span> <span class="o">!=</span> <span class="n">PROTOCOL_VERSION</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Invalid protocol version: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">protocol_version</span><span class="p">)</span>

    <span class="n">_sys_info</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
    <span class="n">unpickler</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">Unpickler</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
    <span class="n">unpickler</span><span class="o">.</span><span class="n">persistent_load</span> <span class="o">=</span> <span class="n">persistent_load</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">unpickler</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>

    <span class="n">deserialized_storage_keys</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>

    <span class="n">offset</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span> <span class="k">if</span> <span class="n">f_should_read_directly</span> <span class="k">else</span> <span class="kc">None</span>
    <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">deserialized_storage_keys</span><span class="p">:</span>
        <span class="k">assert</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">deserialized_objects</span>
        <span class="n">deserialized_objects</span><span class="p">[</span><span class="n">key</span><span class="p">]</span><span class="o">.</span><span class="n">_set_from_file</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">f_should_read_directly</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">offset</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">offset</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">tell</span><span class="p">()</span>

    <span class="k">return</span> <span class="n">result</span>


<span class="k">def</span> <span class="nf">_maybe_decode_ascii</span><span class="p">(</span><span class="n">bytes_str</span><span class="p">):</span>
    <span class="c1"># When using encoding=&#39;bytes&#39; in Py3, some **internal** keys stored as</span>
    <span class="c1"># strings in Py2 are loaded as bytes. This function decodes them with</span>
    <span class="c1"># ascii encoding, one that Py3 uses by default.</span>
    <span class="c1">#</span>
    <span class="c1"># NOTE: This should only be used on internal keys (e.g., `typename` and</span>
    <span class="c1">#       `location` in `persistent_load` below!</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">bytes_str</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">bytes_str</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">bytes_str</span>


<span class="k">def</span> <span class="nf">_get_restore_location</span><span class="p">(</span><span class="n">map_location</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">map_location</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">restore_location</span> <span class="o">=</span> <span class="n">default_restore_location</span>
    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">map_location</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
            <span class="n">location</span> <span class="o">=</span> <span class="n">map_location</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">location</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">default_restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">map_location</span><span class="p">,</span> <span class="n">_string_classes</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">default_restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">map_location</span><span class="p">)</span>
    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">map_location</span><span class="p">,</span> <span class="n">torch</span><span class="o">.</span><span class="n">device</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">default_restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">map_location</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">def</span> <span class="nf">restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
            <span class="n">result</span> <span class="o">=</span> <span class="n">map_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">result</span> <span class="o">=</span> <span class="n">default_restore_location</span><span class="p">(</span><span class="n">storage</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">result</span>
    <span class="k">return</span> <span class="n">restore_location</span>


<span class="k">def</span> <span class="nf">_load</span><span class="p">(</span><span class="n">zip_file</span><span class="p">,</span> <span class="n">map_location</span><span class="p">,</span> <span class="n">pickle_module</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">):</span>
    <span class="n">restore_location</span> <span class="o">=</span> <span class="n">_get_restore_location</span><span class="p">(</span><span class="n">map_location</span><span class="p">)</span>

    <span class="n">loaded_storages</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">load_tensor</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">location</span><span class="p">):</span>
        <span class="n">loaded_storages</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">restore_location</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">location</span><span class="p">)</span>
        <span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;data/</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
        <span class="n">size_long</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="s2">&quot;&lt;Q&quot;</span><span class="p">,</span> <span class="n">size</span><span class="p">)</span>
        <span class="n">tensor_file</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">size_long</span> <span class="o">+</span> <span class="n">zip_file</span><span class="o">.</span><span class="n">get_record</span><span class="p">(</span><span class="n">name</span><span class="p">))</span>
        <span class="n">offset</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">is_real_file</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="n">loaded_storages</span><span class="p">[</span><span class="n">key</span><span class="p">]</span><span class="o">.</span><span class="n">_set_from_file</span><span class="p">(</span><span class="n">tensor_file</span><span class="p">,</span> <span class="n">offset</span><span class="p">,</span> <span class="n">is_real_file</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">persistent_load</span><span class="p">(</span><span class="n">saved_id</span><span class="p">):</span>
        <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">saved_id</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
        <span class="n">typename</span> <span class="o">=</span> <span class="n">_maybe_decode_ascii</span><span class="p">(</span><span class="n">saved_id</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
        <span class="n">data</span> <span class="o">=</span> <span class="n">saved_id</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>

        <span class="k">assert</span> <span class="n">typename</span> <span class="o">==</span> <span class="s1">&#39;storage&#39;</span><span class="p">,</span> \
            <span class="s2">&quot;Unknown typename for persistent_load, expected &#39;storage&#39; but got &#39;</span><span class="si">{}</span><span class="s2">&#39;&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">typename</span><span class="p">)</span>
        <span class="n">data_type</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">location</span><span class="p">,</span> <span class="n">size</span> <span class="o">=</span> <span class="n">data</span>
        <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">loaded_storages</span><span class="p">:</span>
            <span class="n">load_tensor</span><span class="p">(</span><span class="n">data_type</span><span class="p">(</span><span class="n">size</span><span class="p">),</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">_maybe_decode_ascii</span><span class="p">(</span><span class="n">location</span><span class="p">))</span>
        <span class="n">storage</span> <span class="o">=</span> <span class="n">loaded_storages</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">storage</span>

    <span class="c1"># Load the data (which may in turn use `persistent_load` to load tensors)</span>
    <span class="n">data_file</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="n">zip_file</span><span class="o">.</span><span class="n">get_record</span><span class="p">(</span><span class="s1">&#39;data.pkl&#39;</span><span class="p">))</span>
    <span class="n">unpickler</span> <span class="o">=</span> <span class="n">pickle_module</span><span class="o">.</span><span class="n">Unpickler</span><span class="p">(</span><span class="n">data_file</span><span class="p">,</span> <span class="o">**</span><span class="n">pickle_load_args</span><span class="p">)</span>
    <span class="n">unpickler</span><span class="o">.</span><span class="n">persistent_load</span> <span class="o">=</span> <span class="n">persistent_load</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">unpickler</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>

    <span class="k">return</span> <span class="n">result</span>


<span class="k">def</span> <span class="nf">_is_torchscript_zip</span><span class="p">(</span><span class="n">zip_file</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">file_name</span> <span class="ow">in</span> <span class="n">zip_file</span><span class="o">.</span><span class="n">get_all_records</span><span class="p">():</span>
        <span class="n">parts</span> <span class="o">=</span> <span class="n">file_name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">sep</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">parts</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">parts</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;constants.pkl&#39;</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">True</span>
    <span class="k">return</span> <span class="kc">False</span>
</pre></div>

             </article>
             
            </div>
            <footer>
  

  

    <hr>

  

  <div role="contentinfo">
    <p>
        &copy; Copyright 2019, Torch Contributors.

    </p>
  </div>
    
      <div>
        Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
      </div>
     

</footer>

          </div>
        </div>

        <div class="pytorch-content-right" id="pytorch-content-right">
          <div class="pytorch-right-menu" id="pytorch-right-menu">
            <div class="pytorch-side-scroll" id="pytorch-side-scroll-right">
              
            </div>
          </div>
        </div>
      </section>
    </div>

  


  

     
       <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
         <script src="../../_static/jquery.js"></script>
         <script src="../../_static/underscore.js"></script>
         <script src="../../_static/doctools.js"></script>
         <script src="../../_static/language_data.js"></script>
     

  

  <script type="text/javascript" src="../../_static/js/vendor/popper.min.js"></script>
  <script type="text/javascript" src="../../_static/js/vendor/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
  <script type="text/javascript" src="../../_static/js/theme.js"></script>

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>
 
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-90545585-1', 'auto');
  ga('send', 'pageview');

</script>

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-117752657-2"></script>

<script>
  window.dataLayer = window.dataLayer || [];

  function gtag(){dataLayer.push(arguments);}

  gtag('js', new Date());
  gtag('config', 'UA-117752657-2');
</script>

<img height="1" width="1" style="border-style:none;" alt="" src="https://www.googleadservices.com/pagead/conversion/795629140/?label=txkmCPmdtosBENSssfsC&amp;guid=ON&amp;script=0"/>


  <!-- Begin Footer -->

  <div class="container-fluid docs-tutorials-resources" id="docs-tutorials-resources">
    <div class="container">
      <div class="row">
        <div class="col-md-4 text-center">
          <h2>Docs</h2>
          <p>Access comprehensive developer documentation for PyTorch</p>
          <a class="with-right-arrow" href="https://pytorch.org/docs/stable/index.html">View Docs</a>
        </div>

        <div class="col-md-4 text-center">
          <h2>Tutorials</h2>
          <p>Get in-depth tutorials for beginners and advanced developers</p>
          <a class="with-right-arrow" href="https://pytorch.org/tutorials">View Tutorials</a>
        </div>

        <div class="col-md-4 text-center">
          <h2>Resources</h2>
          <p>Find development resources and get your questions answered</p>
          <a class="with-right-arrow" href="https://pytorch.org/resources">View Resources</a>
        </div>
      </div>
    </div>
  </div>

  <footer class="site-footer">
    <div class="container footer-container">
      <div class="footer-logo-wrapper">
        <a href="https://pytorch.org/" class="footer-logo"></a>
      </div>

      <div class="footer-links-wrapper">
        <div class="footer-links-col">
          <ul>
            <li class="list-title"><a href="https://pytorch.org/">PyTorch</a></li>
            <li><a href="https://pytorch.org/get-started">Get Started</a></li>
            <li><a href="https://pytorch.org/features">Features</a></li>
            <li><a href="https://pytorch.org/ecosystem">Ecosystem</a></li>
            <li><a href="https://pytorch.org/blog/">Blog</a></li>
            <li><a href="https://github.com/pytorch/pytorch/blob/master/CONTRIBUTING.md">Contributing</a></li>
          </ul>
        </div>

        <div class="footer-links-col">
          <ul>
            <li class="list-title"><a href="https://pytorch.org/resources">Resources</a></li>
            <li><a href="https://pytorch.org/tutorials">Tutorials</a></li>
            <li><a href="https://pytorch.org/docs/stable/index.html">Docs</a></li>
            <li><a href="https://discuss.pytorch.org" target="_blank">Discuss</a></li>
            <li><a href="https://github.com/pytorch/pytorch/issues" target="_blank">Github Issues</a></li>
            <li><a href="https://pytorch.org/assets/brand-guidelines/PyTorch-Brand-Guidelines.pdf" target="_blank">Brand Guidelines</a></li>
          </ul>
        </div>

        <div class="footer-links-col follow-us-col">
          <ul>
            <li class="list-title">Stay Connected</li>
            <li>
              <div id="mc_embed_signup">
                <form
                  action="https://twitter.us14.list-manage.com/subscribe/post?u=75419c71fe0a935e53dfa4a3f&id=91d0dccd39"
                  method="post"
                  id="mc-embedded-subscribe-form"
                  name="mc-embedded-subscribe-form"
                  class="email-subscribe-form validate"
                  target="_blank"
                  novalidate>
                  <div id="mc_embed_signup_scroll" class="email-subscribe-form-fields-wrapper">
                    <div class="mc-field-group">
                      <label for="mce-EMAIL" style="display:none;">Email Address</label>
                      <input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL" placeholder="Email Address">
                    </div>

                    <div id="mce-responses" class="clear">
                      <div class="response" id="mce-error-response" style="display:none"></div>
                      <div class="response" id="mce-success-response" style="display:none"></div>
                    </div>    <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->

                    <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_75419c71fe0a935e53dfa4a3f_91d0dccd39" tabindex="-1" value=""></div>

                    <div class="clear">
                      <input type="submit" value="" name="subscribe" id="mc-embedded-subscribe" class="button email-subscribe-button">
                    </div>
                  </div>
                </form>
              </div>

            </li>
          </ul>

          <div class="footer-social-icons">
            <a href="https://www.facebook.com/pytorch" target="_blank" class="facebook"></a>
            <a href="https://twitter.com/pytorch" target="_blank" class="twitter"></a>
            <a href="https://www.youtube.com/pytorch" target="_blank" class="youtube"></a>
          </div>
        </div>
      </div>
    </div>
  </footer>

  <div class="cookie-banner-wrapper">
  <div class="container">
    <p class="gdpr-notice">To analyze traffic and optimize your experience, we serve cookies on this site. By clicking or navigating, you agree to allow our usage of cookies. As the current maintainers of this site, Facebook’s Cookies Policy applies. Learn more, including about available controls: <a href="https://www.facebook.com/policies/cookies/">Cookies Policy</a>.</p>
    <img class="close-button" src="../../_static/images/pytorch-x.svg">
  </div>
</div>

  <!-- End Footer -->

  <!-- Begin Mobile Menu -->

  <div class="mobile-main-menu">
    <div class="container-fluid">
      <div class="container">
        <div class="mobile-main-menu-header-container">
          <a class="header-logo" href="https://pytorch.org/" aria-label="PyTorch"></a>
          <a class="main-menu-close-button" href="#" data-behavior="close-mobile-menu"></a>
        </div>
      </div>
    </div>

    <div class="mobile-main-menu-links-container">
      <div class="main-menu">
        <ul>
          <li>
            <a href="https://pytorch.org/get-started">Get Started</a>
          </li>

          <li>
            <a href="https://pytorch.org/features">Features</a>
          </li>

          <li>
            <a href="https://pytorch.org/ecosystem">Ecosystem</a>
          </li>

          <li>
            <a href="https://pytorch.org/mobile">Mobile</a>
          </li>

          <li>
            <a href="https://pytorch.org/hub">PyTorch Hub</a>
          </li>

          <li>
            <a href="https://pytorch.org/blog/">Blog</a>
          </li>

          <li>
            <a href="https://pytorch.org/tutorials">Tutorials</a>
          </li>

          <li class="active">
            <a href="https://pytorch.org/docs/stable/index.html">Docs</a>
          </li>

          <li>
            <a href="https://pytorch.org/resources">Resources</a>
          </li>

          <li>
            <a href="https://github.com/pytorch/pytorch">Github</a>
          </li>
        </ul>
      </div>
    </div>
  </div>

  <!-- End Mobile Menu -->

  <script type="text/javascript" src="../../_static/js/vendor/anchor.min.js"></script>

  <script type="text/javascript">
    $(document).ready(function() {
      mobileMenu.bind();
      mobileTOC.bind();
      pytorchAnchors.bind();
      sideMenus.bind();
      scrollToAnchor.bind();
      highlightNavigation.bind();
      mainMenuDropdown.bind();
      filterTags.bind();

      // Remove any empty p tags that Sphinx adds
      $("[data-tags='null']").remove();

      // Add class to links that have code blocks, since we cannot create links in code blocks
      $("article.pytorch-article a span.pre").each(function(e) {
        $(this).closest("a").addClass("has-code");
      });
    })
  </script>
</body>
</html>